<?php

class XMLHelper {

	private $oDocument;

	public function __construct(DOMDocument $oDocument = null) {

		if(isset($oDocument)) {
			$this->setDocument($oDocument);
    	}

	}

	public function setDocument(DOMDocument $oDocument) {

		$this->oDocument = $oDocument;

	}

	public function createDocumentFromFile(
		$sFileName,
		$bSetDocument = true
		) {

		return $this->createDocument(
			null,
			$sFileName,
			null,
			$bSetDocument
			);

	}

	public function createDocumentFromString(
		$sXml,
		$bSetDocument = true
		) {

		return $this->createDocument(
			null,
			null,
			$sXml,
			$bSetDocument
			);

	}

    protected function createDocument(
		$sRootName,
		$sFileName,
		$sXml,
		$bSetDocument = true
		) {

		$oDocument = new DOMDocument();

		$oDocument->resolveExternals = true;
		$oDocument->substituteEntities = false;
//		$oDocument->preserveWhiteSpace = $bPreserveWhiteSpace;

		$aXmlErrorsBefore = libxml_get_errors();

		if(isset($sRootName)) {
			$oDocument->loadXML("<!DOCTYPE zframe SYSTEM \"" . rtrim($_SERVER["DOCUMENT_ROOT"], "/") . "/symbols.ent\"><" . $sRootName . "></" . $sRootName . ">");
		}
		else if(isset($sFileName)) {

            if(!file_exists($sFileName)) {
                throw new Exception_DocumentFileNotFound();
            }

			$oDocument->load($sFileName);

		}
		else if(isset($sXml)) {
			 $oDocument->loadXML($sXml);
		}

		$aXmlErrorsAfter = libxml_get_errors();

		if(count($aXmlErrorsBefore) < count($aXmlErrorsAfter)) {
			throw new Exception_Xml($aXmlErrorsAfter[count($aXmlErrorsBefore)]);
		}

		$oDocument->xinclude();

		if($bSetDocument) {
			$this->setDocument($oDocument);
		}

		return $oDocument;

	}

	public function createNodeFromString(
		$sXml
		) {

		try {
			$oImplementation = self::createDocumentFromString($sXml, false);
		}
		catch(DOMException $oException) {
			throw new Exception($oException->getMessage());
		}

		return
		    $this->oDocument->importNode(
		        $oImplementation->documentElement,
		        true
		        );

	}

    public function replaceNodeFromString(
		DOMNode $oNode,
		$sXml
		) {

        if(empty($sXml)) {
            $oNode->parentNode->removeChild($oNode);
        }
        else {
            $oNode->parentNode->replaceChild(
                $this->createNodeFromString($sXml),
                $oNode
                );
        }

        return $this;

	}

	public function addNodeFromString(
	    DOMNode $oParentNode,
		$sXml
		) {

        $oParentNode->appendChild(
            $this->createNodeFromString($sXml)
            );

        return $this;

    }

    public function removeChildren(DomNode $oNode) {

        while($oNode->childNodes->length) {
            $oNode->removeChild($oNode->firstChild);
        }

        return $this;

    }

	public function documentToString(DOMDocument $oDocument = null) {

		return
			isset($oDocument)?
				$oDocument->saveXML() :
				$this->oDocument->saveXML()
		    	;

	}

	public function getPIData(DOMProcessingInstruction $oNodePI) {

		$aResult = array();
		$aParts = explode(" ", $oNodePI->data);

		foreach($aParts as $sPart) {

			$aSubParts = explode("=", $sPart);
			$aResult[$aSubParts[0]] = trim($aSubParts[1], "\"");

		}

		return $aResult;

	}

}

?>